"""用户认证模块的视图

定义用户认证相关的API视图，包括注册、登录、用户信息管理等。
"""

from rest_framework import status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import logout
from django.utils.translation import gettext_lazy as _
from django.db.models import Q
from django.utils import timezone
from django.db import transaction

from .models import User, UserProfile, LoginHistory
from .serializers import (
    UserRegistrationSerializer,
    CustomTokenObtainPairSerializer,
    UserSerializer,
    UserProfileSerializer,
    UserUpdateSerializer,
    PasswordChangeSerializer,
    LoginHistorySerializer
)
from apps.common.models import ActivityLog


class AuthViewSet(GenericViewSet, CreateModelMixin):
    """认证视图集
    
    处理用户注册、登录、登出等认证相关操作。
    """
    
    queryset = User.objects.all()
    
    def get_serializer_class(self):
        """根据动作返回对应的序列化器"""
        if self.action == 'register':
            return UserRegistrationSerializer
        return UserSerializer
    
    def get_permissions(self):
        """根据动作设置权限"""
        if self.action in ['register']:
            permission_classes = [permissions.AllowAny]
        else:
            permission_classes = [permissions.IsAuthenticated]
        return [permission() for permission in permission_classes]
    
    @action(detail=False, methods=['post'], permission_classes=[permissions.AllowAny])
    def register(self, request):
        """用户注册
        
        创建新用户账户。
        """
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            
            # 记录活动日志
            ActivityLog.objects.create(
                user=user,
                action='create',
                description=f'用户 {user.username} 注册成功',
                ip_address=self._get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', '')
            )
            
            # 生成JWT token
            refresh = RefreshToken.for_user(user)
            
            return Response({
                'message': '注册成功',
                'user': UserSerializer(user, context={'request': request}).data,
                'tokens': {
                    'refresh': str(refresh),
                    'access': str(refresh.access_token),
                }
            }, status=status.HTTP_201_CREATED)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['post'])
    def logout(self, request):
        """用户登出
        
        使当前用户的refresh token失效。
        """
        try:
            refresh_token = request.data.get('refresh_token')
            if refresh_token:
                token = RefreshToken(refresh_token)
                token.blacklist()
            
            # 更新登录历史
            login_history = LoginHistory.objects.filter(
                user=request.user,
                logout_time__isnull=True
            ).first()
            
            if login_history:
                login_history.logout_time = timezone.now()
                login_history.save()
            
            # 记录活动日志
            ActivityLog.objects.create(
                user=request.user,
                action='logout',
                description=f'用户 {request.user.username} 登出',
                ip_address=self._get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', '')
            )
            
            logout(request)
            
            return Response({
                'message': '登出成功'
            }, status=status.HTTP_200_OK)
        
        except Exception as e:
            return Response({
                'error': '登出失败',
                'detail': str(e)
            }, status=status.HTTP_400_BAD_REQUEST)
    
    def _get_client_ip(self, request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


class CustomTokenObtainPairView(TokenObtainPairView):
    """自定义JWT Token获取视图
    
    处理用户登录并返回JWT token。
    """
    
    serializer_class = CustomTokenObtainPairSerializer


class UserViewSet(GenericViewSet, RetrieveModelMixin, UpdateModelMixin):
    """用户信息视图集
    
    处理用户信息的查看和更新。
    """
    
    queryset = User.objects.all()
    permission_classes = [permissions.IsAuthenticated]
    
    def get_serializer_class(self):
        """根据动作返回对应的序列化器"""
        if self.action == 'update' or self.action == 'partial_update':
            return UserUpdateSerializer
        elif self.action == 'change_password':
            return PasswordChangeSerializer
        return UserSerializer
    
    def get_object(self):
        """获取当前用户对象"""
        if self.action in ['me', 'update_profile', 'change_password']:
            return self.request.user
        return super().get_object()
    
    @action(detail=False, methods=['get'])
    def me(self, request):
        """获取当前用户信息
        
        返回当前登录用户的详细信息。
        """
        serializer = self.get_serializer(request.user)
        return Response(serializer.data)
    
    @action(detail=False, methods=['put', 'patch'])
    @transaction.atomic
    def update_profile(self, request):
        """更新用户信息
        
        更新当前用户的基本信息。
        """
        user = request.user
        serializer = UserUpdateSerializer(user, data=request.data, partial=True)
        
        if serializer.is_valid():
            serializer.save()
            
            # 记录活动日志
            ActivityLog.objects.create(
                user=user,
                action='update',
                description='更新用户信息',
                ip_address=self._get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', '')
            )
            
            return Response({
                'message': '用户信息更新成功',
                'user': UserSerializer(user, context={'request': request}).data
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['post'])
    @transaction.atomic
    def change_password(self, request):
        """修改密码
        
        修改当前用户的登录密码。
        """
        serializer = self.get_serializer(data=request.data, context={'request': request})
        
        if serializer.is_valid():
            serializer.save()
            
            # 记录活动日志
            ActivityLog.objects.create(
                user=request.user,
                action='update',
                description='修改登录密码',
                ip_address=self._get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', '')
            )
            
            return Response({
                'message': '密码修改成功'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['get'])
    def login_history(self, request):
        """获取登录历史
        
        返回当前用户的登录历史记录。
        """
        history = LoginHistory.objects.filter(
            user=request.user
        ).order_by('-login_time')[:20]  # 最近20条记录
        
        serializer = LoginHistorySerializer(history, many=True)
        return Response(serializer.data)
    
    def _get_client_ip(self, request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


class UserProfileViewSet(GenericViewSet, RetrieveModelMixin, UpdateModelMixin):
    """用户配置视图集
    
    处理用户个性化配置的管理。
    """
    
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_object(self):
        """获取当前用户的配置对象"""
        profile, created = UserProfile.objects.get_or_create(
            user=self.request.user
        )
        return profile
    
    @action(detail=False, methods=['get'])
    def me(self, request):
        """获取当前用户配置
        
        返回当前用户的个性化配置。
        """
        profile = self.get_object()
        serializer = self.get_serializer(profile)
        return Response(serializer.data)
    
    @action(detail=False, methods=['put', 'patch'])
    def update_config(self, request):
        """更新用户配置
        
        更新当前用户的个性化配置。
        """
        profile = self.get_object()
        serializer = self.get_serializer(profile, data=request.data, partial=True)
        
        if serializer.is_valid():
            serializer.save()
            
            # 记录活动日志
            ActivityLog.objects.create(
                user=request.user,
                action='update',
                description='更新用户配置',
                ip_address=self._get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', '')
            )
            
            return Response({
                'message': '配置更新成功',
                'profile': serializer.data
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def _get_client_ip(self, request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip
